<template>
  <div class="setting-drawer flex">
    <div class="drawer-left">
      <template v-for="(question, index) in taskStore.taskList" :key="index">
        <AssignTopic
          :index="index + 1"
          :topic-data="question.question_detail"
          :score="question.totalScore"
          :showScore="true"
          :is-relation="!!question.relation_id"
          :show-more="false"
        >
        </AssignTopic>
      </template>
    </div>
    <div class="drawer-right">
      <div class="title flex">
        <div
          class="title-item flex-column"
          v-for="(item, index) in titleList"
          :key="index"
          :class="{ active: settingType == item.value }"
          @click="settingType = item.value"
        >
          {{ item.label }}
          <div class="title-bar"></div>
        </div>
      </div>
      <div class="content">
        <template v-if="settingType === 'batchSetting'">
          <el-form class="topic-form-batch">
            <el-form-item
              :label="item.name"
              v-for="item in taskScoreForm"
              :key="item.type"
            >
              <div class="topic-batch-item">
                <el-input-number
                  v-model="item.score"
                  :step-strictly="true"
                  :step="
                    JSON.stringify(item.type) ===
                    JSON.stringify(QUESTION_CATEGORY_MAP.MULTI_CHOICE)
                      ? 1
                      : 0.5
                  "
                  :disabled="findTopicByType(item.type) ? false : true"
                  :min="0"
                  :max="99"
                  @change="
                    changeScore(
                      JSON.stringify(item.type) ===
                        JSON.stringify(QUESTION_CATEGORY_MAP.MULTI_CHOICE)
                    )
                  "
                  :controls="false"
                  placeholder="每道题分值"
                />
                <template
                  v-if="
                    JSON.stringify(item.type) ===
                    JSON.stringify(QUESTION_CATEGORY_MAP.MULTI_CHOICE)
                  "
                >
                  <el-select
                    :disabled="!item.score || item.score < 1"
                    v-model="item.score_strategy"
                    placeholder="请选择多选题给分策略"
                    size="large"
                  >
                    <el-option
                      v-for="it in STRATEGY_OPTIONS"
                      :key="it.value"
                      :label="it.label"
                      :value="it.value"
                      :disabled="item.score < it.minScore"
                    />
                  </el-select>
                </template>
              </div>
            </el-form-item>
          </el-form>
        </template>
        <template v-else>
          <el-form class="topic-form">
            <template v-for="(item, index) in topicScoreForm" :key="item.id">
              <el-form-item :label="`${index + 1}. ${item.type_name}`">
                <el-popover
                  v-if="item.children"
                  trigger="click"
                  :ref="el => (popoverRefs[index] = el)"
                  placement="bottom"
                  popper-class="score-popover"
                >
                  <div class="score-popover-content flex-column">
                    <div class="title">批量设置得分</div>
                    <div class="content flex">
                      <span>每小题</span>
                      <el-input-number
                        v-model="batchNum"
                        :controls="false"
                        :step-strictly="true"
                        :step="0.5"
                        :min="0"
                        :max="inputMaxValue"
                      />
                      <el-button
                        class="popover-btn"
                        @click="saveBatchNum(index, item.id)"
                      >
                        确定
                      </el-button>
                    </div>
                  </div>
                  <template #reference>
                    <div @click="changePopover(item)" class="total-score">
                      <div class="total-click"></div>
                      <el-input-number
                        v-model="item.score"
                        :disabled="true"
                        :step-strictly="true"
                        class="is-disabled"
                        :step="0.5"
                        :min="0"
                        :max="99"
                      />
                    </div>
                  </template>
                </el-popover>
                <el-input-number
                  v-else
                  v-model="item.score"
                  :step-strictly="true"
                  :step="
                    QUESTION_CATEGORY_MAP.MULTI_CHOICE.includes(
                      item.answer_method
                    )
                      ? 1
                      : 0.5
                  "
                  :min="0"
                  :max="99"
                />
                <span>分</span>
              </el-form-item>
              <template v-if="item.children"
                ><el-form-item
                  :label="`${index + 1}.${id + 1}`"
                  v-for="(it, id) in item.children"
                  :key="it.id"
                >
                  <el-input-number
                    v-model="it.score"
                    :step-strictly="true"
                    :step="0.5"
                    :min="0"
                    :max="99 - (item.children.length - 1) * 0.5"
                    @change="childrenChange(it, item)"
                    @input="childrenInput(item)"
                  />
                  <span>分</span>
                </el-form-item>
              </template>
            </template>
          </el-form>
        </template>
      </div>
      <div class="footer flex-end">
        <el-button
          type="primary"
          class="btn cancel-btn"
          @click="closeShowDrawer"
        >
          取消
        </el-button>
        <el-button type="primary" class="btn" @click="submitChange"
          >保存</el-button
        >
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, nextTick, onMounted, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { QUESTION_CATEGORY_MAP } from '@/constants'
import AssignTopic from '../components/AssignTopic.vue'
import { useTaskStore } from '@/stores'
import { STRATEGY_OPTIONS } from '../util'

const showDrawer = defineModel('visible')
const taskStore = useTaskStore()

// 绑定类型批量设置分数- 仅设置单选题，多选题，填空题
const taskScoreForm = ref([])
const topicScoreForm = ref([])

// 分值设置类型
const settingType = ref('oneSetting')
// 批量得分设置
const batchNum = ref(0)
const inputMaxValue = ref(99)
const popoverRefs = ref([])

const titleList = [
  {
    value: 'batchSetting',
    label: '批量设置'
  },
  {
    value: 'oneSetting',
    label: '逐题设置'
  }
]
const findTopicByType = type => {
  return topicScoreForm.value.find(
    item =>
      ((Array.isArray(type) && type.includes(item.answer_method)) ||
        type === item.answer_method) &&
      !item.children
  )
}
// 当有小题，且小题分数变化，使大题总分超过99时警告
const childrenChange = (children, parent) => {
  parent.score = parent.children.reduce((a, b) => a + b.score, 0)
  if (parent.score > 99) {
    ElMessage.warning('单题总分不能超过99分，请合理分配分数')
    children.score =
      99 -
      parent.children
        .filter(item => item.id != children.id)
        .reduce((a, b) => a + b.score, 0)
    parent.score = parent.children.reduce((a, b) => a + b.score, 0)
  }
}

const childrenInput = parent => {
  nextTick(() => {
    parent.score = parent.children.reduce((a, b) => a + b.score, 0)
  })
}

// 多选题更改分数如果不满足原来的策略的时候要重新格式一下选择的策略
const changeScore = isGoal => {
  if (!isGoal) return
  let temp = taskScoreForm.value.find(
    item =>
      JSON.stringify(item.type) ===
      JSON.stringify(QUESTION_CATEGORY_MAP.MULTI_CHOICE)
  )
  if (
    STRATEGY_OPTIONS.find(it => it.value === temp.score_strategy).minScore >
    temp.score
  ) {
    ElMessage.warning('多选题给分策略需要重新选择！')
    temp.score_strategy = 1
  }
}

// 批量设置大题中的小题分数
const saveBatchNum = (index, id) => {
  let topic = topicScoreForm.value.find(item => item.id === id)
  if (batchNum.value % 0.5 !== 0 || batchNum.value === 0) {
    ElMessage.error('请输入正确的分值！')
    return
  }
  topic.children.forEach(item => {
    item.score = batchNum.value
  })
  topic.score = topic.children.reduce((a, b) => a + b.score, 0)
  batchNum.value = 0
  nextTick(() => {
    // 弹窗关闭的时候让button失去焦点
    popoverRefs.value[index].popperRef.contentRef
      .querySelector('.el-button')
      .blur()
    popoverRefs.value[index].hide()
    batchNum.value = 0
  })
}

// 校验表单
const validateScore = () => {
  return topicScoreForm.value.every(item => {
    // 如果当前项的分值为 0，则返回 false
    if (!item.score) {
      return false
    }
    // 如果当前项有子项，继续检查子项的分值
    if (item.children) {
      // 遍历子项，如果有子项分值为 0，则返回 false
      return item.children.every(subItem => subItem.score)
    }
    return true
  })
}

const submitChange = () => {
  if (settingType.value === 'batchSetting') {
    settingType.value = 'oneSetting'
  }
  // 验证分数
  if (!validateScore()) {
    ElMessage.error('不能有分值为0的题目！')
    return
  }

  // 更新任务列表
  let updateResult = taskStore.taskList.map(item => {
    const newItem = { ...item }
    const topicScore = topicScoreForm.value.find(
      it => it.id === newItem.topic_id
    )
    if (topicScore) {
      newItem.totalScore = topicScore.score
      newItem.subScore = topicScore.children?.map(subItem => ({
        id: subItem.id,
        score: subItem.score
      }))
      newItem.score_strategy = topicScore.score_strategy
    }
    return newItem
  })
  taskStore.updateTakeList(updateResult)

  ElMessage.success('设置成功！')
  closeShowDrawer()
}

// 初始化绑定的分值表单数据
const initScore = () => {
  topicScoreForm.value = taskStore.taskList.map(item => {
    return {
      id: item.topic_id,
      score_strategy:
        QUESTION_CATEGORY_MAP.MULTI_CHOICE.includes(
          item.question_detail.answer_method
        ) && !item.score_strategy
          ? 1
          : item.score_strategy,
      type_name: item.question_detail.question_type,
      type: item.topic_type,
      answer_method: item.question_detail.answer_method,
      score: item.totalScore,
      ...(item.subScore?.length && {
        children: item.subScore.map(subItem => ({
          id: subItem.id,
          score: subItem.score,
          score_strategy: subItem.score_strategy,
          type: subItem.topic_type,
          type_name: item.question_detail.subproblem.find(
            it => it.id === subItem.id
          ).question_type
        }))
      })
    }
  })

  // 初始化 taskScoreForm
  let result = findTopicByType(QUESTION_CATEGORY_MAP.MULTI_CHOICE)
  taskScoreForm.value = [
    {
      name: '单选题',
      type: QUESTION_CATEGORY_MAP.SINGLE_CHOICE
    },
    {
      name: '多选题',
      type: QUESTION_CATEGORY_MAP.MULTI_CHOICE,
      score_strategy: result ? result.score_strategy : 1
    },
    {
      name: '填空题',
      type: QUESTION_CATEGORY_MAP.BLANK
    }
  ]
}

// 当有小题时，可以设置均值
const changePopover = item => {
  inputMaxValue.value = Math.floor((99 / item.children.length) * 2) / 2
}

const closeShowDrawer = () => {
  showDrawer.value = false
}

watch(
  () => taskScoreForm.value,
  () => {
    topicScoreForm.value = topicScoreForm.value.map(item => {
      const taskScore = taskScoreForm.value.find(
        it =>
          ((Array.isArray(it.type) && it.type.includes(item.answer_method)) ||
            item.answer_method === it.type) &&
          !item.children
      )
      return taskScore?.score !== undefined
        ? {
            ...item,
            score: taskScore.score,
            score_strategy: taskScore.score_strategy
          }
        : item
    })
  },
  {
    deep: true
  }
)

onMounted(() => {
  initScore()
  settingType.value = 'oneSetting'
})
</script>

<style lang="less" scoped>
.setting-drawer {
  background-color: rgba(0, 0, 0, 0.5);
  position: absolute;
  z-index: 1000;
  height: 100vh;
  top: 0;
  left: 0;
  width: 100vw;
  overflow: hidden;
  .drawer-left {
    width: calc(100vw - 696px);
    height: calc(100% - 40px);
    padding: 20px;
    overflow: auto;
    &::-webkit-scrollbar {
      display: none; /* 隐藏滚动条 */
    }
  }
}
.drawer-right {
  position: relative;
  background-color: white;
  width: 656px;
  height: 100%;
  .title {
    padding: 26px;
    gap: 40px;
    color: #495270;
    .title-item {
      font-size: 18px;
      font-weight: bold;
      height: 30px;
      align-items: center;
      &:hover {
        cursor: pointer;
      }
    }
    .title-bar {
      display: none;
      width: 10px;
      border: 1px solid #428fff;
    }
    .active {
      color: #428fff;
      .title-bar {
        display: block;
      }
    }
  }
  .footer {
    bottom: 0;
    right: 0;
    position: absolute;
    padding: 6px 26px;
    .btn {
      width: 72px;
      height: 36px;
    }
    .cancel-btn {
      border-color: #428fff;
      color: #428fff;
      background-color: #fff;
      &:hover {
        background-color: #ecf5ff;
      }
    }
  }
  .content {
    max-height: 80%;
    overflow-y: auto;
    padding: 26px;
    padding-top: 0;
  }
}
:deep(.el-form) {
  .el-form-item__label {
    color: #131313;
  }
  .el-form-item {
    justify-content: space-between;
    .el-form-item__content {
      color: rgba(4, 11, 26, 0.75);
      flex: none;
    }
  }
}
.topic-form-batch {
  .el-form-item {
    margin-bottom: 26px;
  }
  .topic-batch-item {
    width: 507px;
    :deep(.el-input-number) {
      width: 100%;
      height: 40px;
      .el-input__inner {
        text-align: left;
      }
    }
    :deep(.el-select) {
      width: 100% !important;
      margin-top: 16px;
      .el-select__wrapper {
        height: 40px;
        padding: 8px 16px;
      }
    }
  }
}

.topic-form {
  :deep(.el-form-item) {
    margin-bottom: 40px;
    align-items: center;
    .el-form-item__content {
      gap: 8px;
    }
    .el-input-number {
      width: 150px;
      height: 40px;
      .el-input-number__decrease,
      .el-input-number__increase {
        width: 36px;
        color: #909399;
      }
      .el-input-number__increase {
        border-radius: 0px 8px 8px 0px;
      }
    }
  }
  .total-score {
    position: relative;
    .total-click {
      cursor: pointer;
      z-index: 10;
      opacity: 0;
      position: absolute;
      width: 100%;
      height: 100%;
    }
  }
}
</style>
<!-- eslint-disable -->
<style lang="less">
.score-popover {
  width: 300px !important;
  height: 148px;
  transform: translateX(-38px);
  padding: 0 !important;
  .score-popover-content {
    align-items: center;
    .title {
      font-size: 20px;
      color: #495270;
      font-weight: bold;
      text-align: center;
      padding: 24px 36px;
      padding-bottom: 26px;
    }
    .content {
      gap: 16px;
      color: #616161;
    }
    .popover-btn {
      width: 32px;
      height: 29px;
      border: none;
      line-height: 28.8px;
      color: #428fff;
      &:hover {
        cursor: pointer;
      }
    }
  }
  .el-input-number {
    width: 116px;
    height: 36px;
    .el-input__wrapper {
      padding: 6px 15px;
      .el-input__inner {
        text-align: left;
        color: #616161;
      }
    }
  }
}
</style>
